/**
 * WebGL Playground 代码模板
 */

export interface CodeTemplate {
  vertex: string
  fragment: string
  js: string
}

export const templates: Record<string, CodeTemplate> = {
  line: {
    vertex: `attribute vec4 a_Position;
void main() {
  gl_Position = a_Position;
}`,
    fragment: `precision mediump float;
uniform vec4 u_FragColor;
void main() {
  gl_FragColor = u_FragColor;
}`,
    js: `// 获取WebGL上下文
const gl = canvas.getContext('webgl');
if (!gl) {
  console.error('无法获取WebGL上下文');
  return;
}

// 创建着色器
function createShader(gl, type, source) {
  const shader = gl.createShader(type);
  gl.shaderSource(shader, source);
  gl.compileShader(shader);
  if (!gl.getShaderParameter(shader, gl.COMPILE_STATUS)) {
    console.error('着色器编译错误:', gl.getShaderInfoLog(shader));
    gl.deleteShader(shader);
    return null;
  }
  return shader;
}

// 创建程序
function createProgram(gl, vertexShader, fragmentShader) {
  const program = gl.createProgram();
  gl.attachShader(program, vertexShader);
  gl.attachShader(program, fragmentShader);
  gl.linkProgram(program);
  if (!gl.getProgramParameter(program, gl.LINK_STATUS)) {
    console.error('程序链接错误:', gl.getProgramInfoLog(program));
    return null;
  }
  return program;
}

// 创建着色器程序
const vertexShader = createShader(gl, gl.VERTEX_SHADER, vertexShaderSource);
const fragmentShader = createShader(gl, gl.FRAGMENT_SHADER, fragmentShaderSource);
const program = createProgram(gl, vertexShader, fragmentShader);

gl.useProgram(program);

// 设置顶点数据（正方形的4个顶点）
const vertices = new Float32Array([
  -0.5, -0.5,  // 左下
   0.5, -0.5,  // 右下
   0.5,  0.5,  // 右上
  -0.5,  0.5   // 左上
]);
const vertexBuffer = gl.createBuffer();
gl.bindBuffer(gl.ARRAY_BUFFER, vertexBuffer);
gl.bufferData(gl.ARRAY_BUFFER, vertices, gl.STATIC_DRAW);

// 设置顶点属性
const a_Position = gl.getAttribLocation(program, 'a_Position');
gl.vertexAttribPointer(a_Position, 2, gl.FLOAT, false, 0, 0);
gl.enableVertexAttribArray(a_Position);

// 设置线条颜色（蓝色）
const u_FragColor = gl.getUniformLocation(program, 'u_FragColor');
gl.uniform4f(u_FragColor, 0.25, 0.62, 1.0, 1.0);

// 设置线宽（某些浏览器可能不支持大于1的线宽）
gl.lineWidth(1.0);

// 清空并绘制
gl.clearColor(0.0, 0.0, 0.0, 1.0);
gl.clear(gl.COLOR_BUFFER_BIT);

// 使用LINE_LOOP模式绘制闭合的线条
gl.drawArrays(gl.LINE_LOOP, 0, 4);

console.log('线条绘制完成！');
console.log('提示：可以尝试修改drawArrays的模式为gl.LINES或gl.LINE_STRIP');`
  },
  point: {
    vertex: `attribute vec4 a_Position;
uniform float u_PointSize;
void main() {
  gl_Position = a_Position;
  gl_PointSize = u_PointSize;
}`,
    fragment: `precision mediump float;
uniform vec4 u_FragColor;
void main() {
  gl_FragColor = u_FragColor;
}`,
    js: `// 获取WebGL上下文
const gl = canvas.getContext('webgl');
if (!gl) {
  console.error('无法获取WebGL上下文');
  return;
}

// 创建着色器
function createShader(gl, type, source) {
  const shader = gl.createShader(type);
  gl.shaderSource(shader, source);
  gl.compileShader(shader);
  if (!gl.getShaderParameter(shader, gl.COMPILE_STATUS)) {
    console.error('着色器编译错误:', gl.getShaderInfoLog(shader));
    gl.deleteShader(shader);
    return null;
  }
  return shader;
}

// 创建程序
function createProgram(gl, vertexShader, fragmentShader) {
  const program = gl.createProgram();
  gl.attachShader(program, vertexShader);
  gl.attachShader(program, fragmentShader);
  gl.linkProgram(program);
  if (!gl.getProgramParameter(program, gl.LINK_STATUS)) {
    console.error('程序链接错误:', gl.getProgramInfoLog(program));
    return null;
  }
  return program;
}

// 创建着色器程序
const vertexShader = createShader(gl, gl.VERTEX_SHADER, vertexShaderSource);
const fragmentShader = createShader(gl, gl.FRAGMENT_SHADER, fragmentShaderSource);
const program = createProgram(gl, vertexShader, fragmentShader);

gl.useProgram(program);

// 设置顶点数据
const vertices = new Float32Array([0.0, 0.0, 0.0]);
const vertexBuffer = gl.createBuffer();
gl.bindBuffer(gl.ARRAY_BUFFER, vertexBuffer);
gl.bufferData(gl.ARRAY_BUFFER, vertices, gl.STATIC_DRAW);

// 设置顶点属性
const a_Position = gl.getAttribLocation(program, 'a_Position');
gl.vertexAttribPointer(a_Position, 3, gl.FLOAT, false, 0, 0);
gl.enableVertexAttribArray(a_Position);

// 设置点大小
const u_PointSize = gl.getUniformLocation(program, 'u_PointSize');
gl.uniform1f(u_PointSize, 20.0);

// 设置颜色
const u_FragColor = gl.getUniformLocation(program, 'u_FragColor');
gl.uniform4f(u_FragColor, 1.0, 0.0, 0.0, 1.0);

// 清空并绘制
gl.clearColor(0.0, 0.0, 0.0, 1.0);
gl.clear(gl.COLOR_BUFFER_BIT);
gl.drawArrays(gl.POINTS, 0, 1);

console.log('绘制完成！');`
  },
  triangle: {
    vertex: `attribute vec4 a_Position;
attribute vec4 a_Color;
varying vec4 v_Color;
void main() {
  gl_Position = a_Position;
  v_Color = a_Color;
}`,
    fragment: `precision mediump float;
varying vec4 v_Color;
void main() {
  gl_FragColor = v_Color;
}`,
    js: `const gl = canvas.getContext('webgl');
if (!gl) {
  console.error('无法获取WebGL上下文');
  return;
}

function createShader(gl, type, source) {
  const shader = gl.createShader(type);
  gl.shaderSource(shader, source);
  gl.compileShader(shader);
  if (!gl.getShaderParameter(shader, gl.COMPILE_STATUS)) {
    console.error('着色器编译错误:', gl.getShaderInfoLog(shader));
    gl.deleteShader(shader);
    return null;
  }
  return shader;
}

function createProgram(gl, vertexShader, fragmentShader) {
  const program = gl.createProgram();
  gl.attachShader(program, vertexShader);
  gl.attachShader(program, fragmentShader);
  gl.linkProgram(program);
  if (!gl.getProgramParameter(program, gl.LINK_STATUS)) {
    console.error('程序链接错误:', gl.getProgramInfoLog(program));
    return null;
  }
  return program;
}

const vertexShader = createShader(gl, gl.VERTEX_SHADER, vertexShaderSource);
const fragmentShader = createShader(gl, gl.FRAGMENT_SHADER, fragmentShaderSource);
const program = createProgram(gl, vertexShader, fragmentShader);

gl.useProgram(program);

// 顶点数据（位置 + 颜色）
const verticesColors = new Float32Array([
  0.0, 0.5, 0.0,    1.0, 0.0, 0.0, 1.0,  // 顶点1: 红色
  -0.5, -0.5, 0.0,  0.0, 1.0, 0.0, 1.0,  // 顶点2: 绿色
  0.5, -0.5, 0.0,   0.0, 0.0, 1.0, 1.0   // 顶点3: 蓝色
]);

const FSIZE = verticesColors.BYTES_PER_ELEMENT;
const buffer = gl.createBuffer();
gl.bindBuffer(gl.ARRAY_BUFFER, buffer);
gl.bufferData(gl.ARRAY_BUFFER, verticesColors, gl.STATIC_DRAW);

const a_Position = gl.getAttribLocation(program, 'a_Position');
gl.vertexAttribPointer(a_Position, 3, gl.FLOAT, false, FSIZE * 7, 0);
gl.enableVertexAttribArray(a_Position);

const a_Color = gl.getAttribLocation(program, 'a_Color');
gl.vertexAttribPointer(a_Color, 4, gl.FLOAT, false, FSIZE * 7, FSIZE * 3);
gl.enableVertexAttribArray(a_Color);

gl.clearColor(0.0, 0.0, 0.0, 1.0);
gl.clear(gl.COLOR_BUFFER_BIT);
gl.drawArrays(gl.TRIANGLES, 0, 3);

console.log('彩色三角形绘制完成！');`
  },
  rotation: {
    vertex: `attribute vec4 a_Position;
uniform mat4 u_ModelMatrix;
void main() {
  gl_Position = u_ModelMatrix * a_Position;
}`,
    fragment: `precision mediump float;
void main() {
  gl_FragColor = vec4(1.0, 0.5, 0.0, 1.0);
}`,
    js: `const gl = canvas.getContext('webgl');
if (!gl) {
  console.error('无法获取WebGL上下文');
  return;
}

function createShader(gl, type, source) {
  const shader = gl.createShader(type);
  gl.shaderSource(shader, source);
  gl.compileShader(shader);
  if (!gl.getShaderParameter(shader, gl.COMPILE_STATUS)) {
    console.error('着色器编译错误:', gl.getShaderInfoLog(shader));
    gl.deleteShader(shader);
    return null;
  }
  return shader;
}

function createProgram(gl, vertexShader, fragmentShader) {
  const program = gl.createProgram();
  gl.attachShader(program, vertexShader);
  gl.attachShader(program, fragmentShader);
  gl.linkProgram(program);
  if (!gl.getProgramParameter(program, gl.LINK_STATUS)) {
    console.error('程序链接错误:', gl.getProgramInfoLog(program));
    return null;
  }
  return program;
}

const vertexShader = createShader(gl, gl.VERTEX_SHADER, vertexShaderSource);
const fragmentShader = createShader(gl, gl.FRAGMENT_SHADER, fragmentShaderSource);
const program = createProgram(gl, vertexShader, fragmentShader);

gl.useProgram(program);

const vertices = new Float32Array([
  0.0, 0.3, 0.0,
  -0.3, -0.3, 0.0,
  0.3, -0.3, 0.0
]);

const buffer = gl.createBuffer();
gl.bindBuffer(gl.ARRAY_BUFFER, buffer);
gl.bufferData(gl.ARRAY_BUFFER, vertices, gl.STATIC_DRAW);

const a_Position = gl.getAttribLocation(program, 'a_Position');
gl.vertexAttribPointer(a_Position, 3, gl.FLOAT, false, 0, 0);
gl.enableVertexAttribArray(a_Position);

const u_ModelMatrix = gl.getUniformLocation(program, 'u_ModelMatrix');
let angle = 0;

function render() {
  angle += 0.02;
  const radian = angle;
  const cos = Math.cos(radian);
  const sin = Math.sin(radian);
  
  // 旋转矩阵
  const modelMatrix = new Float32Array([
    cos, sin, 0, 0,
    -sin, cos, 0, 0,
    0, 0, 1, 0,
    0, 0, 0, 1
  ]);
  
  gl.uniformMatrix4fv(u_ModelMatrix, false, modelMatrix);
  gl.clearColor(0.0, 0.0, 0.0, 1.0);
  gl.clear(gl.COLOR_BUFFER_BIT);
  gl.drawArrays(gl.TRIANGLES, 0, 3);
  
  requestAnimationFrame(render);
}

render();
console.log('旋转动画启动！');`
  },
  gradient: {
    vertex: `attribute vec4 a_Position;
void main() {
  gl_Position = a_Position;
}`,
    fragment: `precision mediump float;
uniform vec2 u_Resolution;
uniform float u_Time;

void main() {
  vec2 uv = gl_FragCoord.xy / u_Resolution;
  vec3 color = 0.5 + 0.5 * cos(u_Time + uv.xyx + vec3(0, 2, 4));
  gl_FragColor = vec4(color, 1.0);
}`,
    js: `const gl = canvas.getContext('webgl');
if (!gl) {
  console.error('无法获取WebGL上下文');
  return;
}

function createShader(gl, type, source) {
  const shader = gl.createShader(type);
  gl.shaderSource(shader, source);
  gl.compileShader(shader);
  if (!gl.getShaderParameter(shader, gl.COMPILE_STATUS)) {
    console.error('着色器编译错误:', gl.getShaderInfoLog(shader));
    gl.deleteShader(shader);
    return null;
  }
  return shader;
}

function createProgram(gl, vertexShader, fragmentShader) {
  const program = gl.createProgram();
  gl.attachShader(program, vertexShader);
  gl.attachShader(program, fragmentShader);
  gl.linkProgram(program);
  if (!gl.getProgramParameter(program, gl.LINK_STATUS)) {
    console.error('程序链接错误:', gl.getProgramInfoLog(program));
    return null;
  }
  return program;
}

const vertexShader = createShader(gl, gl.VERTEX_SHADER, vertexShaderSource);
const fragmentShader = createShader(gl, gl.FRAGMENT_SHADER, fragmentShaderSource);
const program = createProgram(gl, vertexShader, fragmentShader);

gl.useProgram(program);

const vertices = new Float32Array([
  -1, 1, 0,
  -1, -1, 0,
  1, 1, 0,
  1, -1, 0
]);

const buffer = gl.createBuffer();
gl.bindBuffer(gl.ARRAY_BUFFER, buffer);
gl.bufferData(gl.ARRAY_BUFFER, vertices, gl.STATIC_DRAW);

const a_Position = gl.getAttribLocation(program, 'a_Position');
gl.vertexAttribPointer(a_Position, 3, gl.FLOAT, false, 0, 0);
gl.enableVertexAttribArray(a_Position);

const u_Resolution = gl.getUniformLocation(program, 'u_Resolution');
const u_Time = gl.getUniformLocation(program, 'u_Time');

gl.uniform2f(u_Resolution, canvas.width, canvas.height);

let startTime = Date.now();

function render() {
  const time = (Date.now() - startTime) / 1000;
  gl.uniform1f(u_Time, time);
  gl.clear(gl.COLOR_BUFFER_BIT);
  gl.drawArrays(gl.TRIANGLE_STRIP, 0, 4);
  requestAnimationFrame(render);
}

render();
console.log('渐变动画启动！');`
  }
}

export const templateOptions = [
  { label: '线条绘制', value: 'line' },
  { label: '基础点绘制', value: 'point' },
  { label: '彩色三角形', value: 'triangle' },
  { label: '旋转动画', value: 'rotation' },
  { label: '渐变效果', value: 'gradient' }
]

